package cn.kuporo.seckill.order.application.service.impl;

import cn.kuporo.seckill.common.cache.distribute.DistributedCacheService;
import cn.kuporo.seckill.common.constants.MQConstants;
import cn.kuporo.seckill.common.constants.RedisConstants;
import cn.kuporo.seckill.common.exception.ErrorCode;
import cn.kuporo.seckill.common.exception.SeckillException;
import cn.kuporo.seckill.order.application.model.command.SeckillOrderCommand;
import cn.kuporo.seckill.common.model.dto.SeckillOrderSubmitDTO;
import cn.kuporo.seckill.order.application.model.task.SeckillOrderTask;
import cn.kuporo.seckill.order.application.service.OrderTaskGenerateService;
import cn.kuporo.seckill.order.application.service.PlaceOrderTaskService;
import cn.kuporo.seckill.order.application.service.SeckillSubmitOrderService;
import lombok.RequiredArgsConstructor;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.concurrent.TimeUnit;

/**
 * @author: kuporo
 * @since: 2025/7/11
 * @description: 异步提交订单
 */
@Service
@ConditionalOnProperty(name = "submit.order.type", havingValue = "async")
@RequiredArgsConstructor
public class SeckillAsyncSubmitOrderServiceImpl extends SeckillBaseSubmitOrderServiceImpl implements SeckillSubmitOrderService {
    private final OrderTaskGenerateService orderTaskGenerateService;
    private final PlaceOrderTaskService placeOrderTaskService;
    private final DistributedCacheService distributedCacheService;

    @Override
    public SeckillOrderSubmitDTO saveSeckillOrder(Long userId, SeckillOrderCommand seckillOrderCommand) {
        // 进行基本的检查
        this.checkSeckillOrder(userId, seckillOrderCommand);
        // 生成订单任务id
        String orderTaskId = orderTaskGenerateService.generatePlaceOrderTaskId(userId, seckillOrderCommand.getGoodsId());
        // 构造下单任务
        SeckillOrderTask seckillOrderTask = new SeckillOrderTask(MQConstants.TOPIC_ORDER_MSG, orderTaskId, userId, seckillOrderCommand);
        // 提交订单
        boolean isSubmit = placeOrderTaskService.submitOrderTask(seckillOrderTask);
        if (!isSubmit){
            // 提交失败
            throw new SeckillException(ErrorCode.ORDER_FAILED);
        }
        return new SeckillOrderSubmitDTO(orderTaskId, seckillOrderCommand.getGoodsId(), RedisConstants.TYPE_TASK);
    }

    @Override
    @Transactional
    public void handlePlaceOrderTask(SeckillOrderTask seckillOrderTask) {
        Long orderId = seckillPlaceOrderService.placeOrder(seckillOrderTask.getUserId(), seckillOrderTask.getSeckillOrderCommand());
        if (orderId != null){
            String key = RedisConstants.getKey(RedisConstants.ORDER_TASK_ORDER_ID_KEY, seckillOrderTask.getOrderTaskId());
            distributedCacheService.put(key, orderId, RedisConstants.ORDER_TASK_EXPIRE_SECONDS, TimeUnit.SECONDS);
        }
    }
}
